%{
#include <stdio.h>
#include <stdlib.h>

#include "CSSGrammer.h"
#define YYPRINT(S) printf("%s : %s\n", S, yytext);


%}

%option noyywrap
%option case-insensitive

h     		[0-9a-z]
nonascii 	[\200-\377]
unicode	 	\\{h}{1,6}(\r\n|[ \t\r\n\f])?
escape		{unicode}|\\[^\r\n\f0-9a-f]
nmstart		[_a-z]|{nonascii}|{escape}
nmchar		[_a-z0-9-]|{nonascii}|{escape}
string1		\"([^\n\r\f\\"]|\\{nl}|{escape})*\"
string2		\'([^\n\r\f\\']|\\{nl}|{escape})*\'
invalid1	\"([^\n\r\f\\"]|\\{nl}|{escape})*
invalid2	\'([^\n\r\f\\']|\\{nl}|{escape})*

comment		\/\*[^*]*\*+([^/*][^*]*\*+)*\/
ident		-?{nmstart}{nmchar}*
name		{nmchar}+
num			[0-9]+|[0-9]*"."[0-9]+
string		{string1}|{string2}
invalid		{invalid1}|{invalid2}
url			([!#$%&*-~]|{nonascii}|{escape})*
s			[ \t\r\n\f]+
w			{s}?
nl			\n|\r\n|\r|\f

A			a|\\0{0,4}(41|61)(\r\n|[ \t\r\n\f])?
C			c|\\0{0,4}(43|63)(\r\n|[ \t\r\n\f])?
D			d|\\0{0,4}(44|64)(\r\n|[ \t\r\n\f])?
E			e|\\0{0,4}(45|65)(\r\n|[ \t\r\n\f])?
G			g|\\0{0,4}(47|67)(\r\n|[ \t\r\n\f])?|\\g
H			h|\\0{0,4}(48|68)(\r\n|[ \t\r\n\f])?|\\h
I			i|\\0{0,4}(49|69)(\r\n|[ \t\r\n\f])?|\\i
K			k|\\0{0,4}(4b|6b)(\r\n|[ \t\r\n\f])?|\\k
L           l|\\0{0,4}(4c|6c)(\r\n|[ \t\r\n\f])?|\\l
M			m|\\0{0,4}(4d|6d)(\r\n|[ \t\r\n\f])?|\\m
N			n|\\0{0,4}(4e|6e)(\r\n|[ \t\r\n\f])?|\\n
O			o|\\0{0,4}(4f|6f)(\r\n|[ \t\r\n\f])?|\\o
P			p|\\0{0,4}(50|70)(\r\n|[ \t\r\n\f])?|\\p
R			r|\\0{0,4}(52|72)(\r\n|[ \t\r\n\f])?|\\r
S			s|\\0{0,4}(53|73)(\r\n|[ \t\r\n\f])?|\\s
T			t|\\0{0,4}(54|74)(\r\n|[ \t\r\n\f])?|\\t
U           u|\\0{0,4}(55|75)(\r\n|[ \t\r\n\f])?|\\u
X			x|\\0{0,4}(58|78)(\r\n|[ \t\r\n\f])?|\\x
Z			z|\\0{0,4}(5a|7a)(\r\n|[ \t\r\n\f])?|\\z

%%
{s}			{return S;}

\/\*[^*]*\*+([^/*][^*]*\*+)*\/		/* ignore comments */

"<!--"		{YYPRINT("CD0");return CDO;}
"-->"			{YYPRINT("CD1"); return CDC;}
"~="			{return INCLUDES;}
"|="			{return DASHMATCH;}

{string}		{
					yylval.text = (char*)malloc(yyleng + 1);
					strcpy(yylval.text, yytext);
					return STRING;}
{invalid}		{return INVALID; /* unclosed string */}

{ident}			{
					yylval.text = (char*)malloc(yyleng + 1);
					strcpy(yylval.text, yytext);
					return IDENT;
				}

"#"{name}		{
					yylval.text = (char*)malloc(yyleng);
					strcpy(yylval.text, yytext + 1);
					return HASH;
				}

@{I}{M}{P}{O}{R}{T}	{return IMPORT_SYM;}
@{P}{A}{G}{E}		{return PAGE_SYM;}
@{M}{E}{D}{I}{A}	{return MEDIA_SYM;}
"@charset "		{return CHARSET_SYM;}

"!"({w}|{comment})*{I}{M}{P}{O}{R}{T}{A}{N}{T}	{return IMPORTANT_SYM;}

{num}{E}{M}		{
					yylval.float_value = (float)atof(yytext);
					return EMS;
				}
{num}{E}{X}		{
					yylval.float_value = (float)atof(yytext);
					return EXS;}
{num}{P}{X}		{
					yylval.float_value = (float)atof(yytext);
					return PXS;
				}
{num}{C}{M}		{
					yylval.float_value = (float)atof(yytext);
					return CMS;
				}
{num}{M}{M}		{
					yylval.float_value = (float)atof(yytext);
					return MMS;
				}
{num}{I}{N}		{
					yylval.float_value = (float)atof(yytext);
					return INS;
				}
{num}{P}{T}		{
					yylval.float_value = (float)atof(yytext);
					return PTS;
				}
{num}{P}{C}		{
					yylval.float_value = (float)atof(yytext);
					return PCS;
				}
{num}{D}{E}{G}		{
						yylval.float_value = (float)atof(yytext);
						return DEGS;
					}
{num}{R}{A}{D}		{
						yylval.float_value = (float)atof(yytext);
						return RADS;
					}
{num}{G}{R}{A}{D}	{
						yylval.float_value = (float)atof(yytext);
						return GRADS;
					}
{num}{M}{S}		{return MSECS;}
{num}{S}		{return SECS;}
{num}{H}{Z}		{return HERZS;}
{num}{K}{H}{Z}		{return KHERZS;}
{num}{ident}		{return DIMENSION;}

{num}%			{
					yylval.float_value = (float)atof(yytext);
					return PERCENTAGE;
				}
{num}			{
					yylval.float_value = (float)atof(yytext);
					return NUMBER;
				}

{U}{R}{L}"("{w}{string}{w}")" {
							       //YYPRINT("URI");
								   yylval.text = (char*)malloc(yyleng + 1);
								   strcpy(yylval.text, yytext);
							       return URI;
							  }
{U}{R}{L}"("{w}{url}{w}")" {
								//YYPRINT("URI");
								yylval.text = (char*)malloc(yyleng + 1);
								strcpy(yylval.text, yytext);
								return URI;}

{ident}"("		{
					//YYPRINT("FUNCTION");
					return FUNCTION;
				}

.			{   YYPRINT("char");
				return *yytext;
			}
%%
